package com.hzncc.flowable_diboot.service.impl;

import com.diboot.core.util.S;
import com.diboot.file.entity.FileRecord;
import com.diboot.file.service.FileStorageService;
import com.diboot.file.util.FileHelper;
import com.diboot.file.util.HttpHelper;
import com.hzncc.flowable_diboot.util.MinioUtil;
import io.minio.*;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import java.io.InputStream;

/**
 * minio文件存储
 */
@Log4j2
public class MinioFileStorageServiceImpl implements FileStorageService {

    @Value("${minio.defaultBucket}")
    public String bucket;
    @Resource
    public MinioUtil util;
    @Override
    public FileRecord save(MultipartFile file) throws Exception {
        // 获取client
        MinioClient client =util.getClient();
        String fileUid;
        String ext;
        String newFileName;
        try {
            // 检查存储桶是否存在
            boolean found = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            }
            //文件唯一名
            fileUid = S.newUuid();
            ext = FileHelper.getFileExtByName(file.getOriginalFilename());
            newFileName = fileUid + "." + ext;
            String fileFullPath = FileHelper.getFullPath(newFileName);
            // 上传文件
            client.putObject(PutObjectArgs.builder()
                    .bucket(bucket)
                    .object(newFileName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .build());
            log.info(file.getOriginalFilename() + "文件上传成功");
            String url = util.createNginxUrl(newFileName);
            return (new FileRecord(fileUid)).setFileName(file.getOriginalFilename()).setFileType(ext).setFileSize(file.getSize()).setStoragePath(newFileName).setAccessUrl(url);
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            client.close();
        }
    }

    @Override
    public FileRecord save(InputStream inputStream, String fileName, long size) throws Exception {
        // 获取client
        MinioClient client = util.getClient();
        String fileUid;
        String ext;
        String newFileName;
        try {
            // 检查存储桶是否存在
            boolean found = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            }
            fileUid = S.newUuid();
            ext = FileHelper.getFileExtByName(fileName);
            newFileName = fileUid + "." + ext;
            client.putObject(PutObjectArgs.builder()
                    .bucket(bucket) // 存储桶
                    .object(newFileName) // 文件名
                    .stream(inputStream, size, -1) // 文件流
                    .build());
            log.info(fileName + "文件上传成功");
        String url = util.createNginxUrl(newFileName);
        return (new FileRecord(fileUid)).setFileName(fileName).setFileType(ext).setFileSize(size).setStoragePath(newFileName).setAccessUrl(url);
        } catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            client.close();
        }
    }

    @Override
    public InputStream getFile(String filePath) throws Exception {
        // 获取client
        MinioClient client = util.getClient();
        GetObjectResponse object;
        try {
            // 检查存储桶是否存在
            boolean found = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                log.info(filePath + "文件不存在");
                return null;
            }
            object = client.getObject(GetObjectArgs.builder()
                    .bucket(bucket)
                    .object(filePath)
                    .build());
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            client.close();
        }
        return object;
    }

    @Override
    public void download(FileRecord uploadFile, HttpServletResponse response) throws Exception {
        // 获取client
        MinioClient client = util.getClient();
        GetObjectResponse object;
        try {
            // 检查存储桶是否存在
            boolean found = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                log.info(uploadFile.getFileName() + "文件不存在");
                return;
            }
            object = client.getObject(GetObjectArgs.builder()
                    .bucket(bucket)
                    .object(uploadFile.getStoragePath())
                    .build());
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            client.close();
        }
        HttpHelper.downloadFile(object, uploadFile.getFileSize(), uploadFile.getFileName(), response);
    }

    @Override
    public boolean delete(String filePath) {
        // 获取client
        MinioClient client = util.getClient();
        try {
            // 检查存储桶是否存在
            boolean found = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
            if (!found) {
                log.info(filePath + "文件不存在");
                return false;
            }
            client.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucket)
                    .object(filePath)
                    .build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                log.info("文件删除失败" + e.getMessage());
            }
        }
        return true;
    }
}
